"""适配器工厂

负责创建和管理不同类型的区块链适配器实例。
"""

from typing import Dict, Any, Optional
from utils.logger import get_logger
from utils.exceptions import ChainNotSupportedException, AdapterException
from adapters.base_adapter import BaseBlockchainAdapter
from adapters.fisco_bcos_adapter import FiscoBcosAdapter
from adapters.chainmaker_adapter import ChainMakerAdapter
from adapters.jdchain_adapter import JDChainAdapter
from adapters.xuperchain_adapter import XuperChainAdapter
# from adapters.ethernet_adapter import EthereumAdapter  # 已移除
from adapters.thanos_adapter import ThanosAdapter

logger = get_logger(__name__)

class AdapterFactory:
    """适配器工厂类
    
    负责:
    1. 创建不同类型的区块链适配器实例
    2. 管理适配器实例的生命周期
    3. 提供适配器实例的缓存和复用
    """
    
    def __init__(self):
        """初始化适配器工厂"""
        self.adapters = {}  # 适配器实例缓存
        self.adapter_classes = {
            'fisco_bcos': FiscoBcosAdapter,
            'chainmaker': ChainMakerAdapter,
            'jdchain': JDChainAdapter,
            'xuperchain': XuperChainAdapter,
            'thanos': ThanosAdapter
        }
    
    def get_adapter(self, chain_type: str, config: Dict[str, Any] = None) -> BaseBlockchainAdapter:
        """获取指定类型的区块链适配器实例
        
        Args:
            chain_type: 区块链类型
            config: 适配器配置参数
            
        Returns:
            区块链适配器实例
            
        Raises:
            ChainNotSupportedException: 如果指定的区块链类型不受支持
        """
        # 检查是否支持该区块链类型
        if chain_type not in self.adapter_classes:
            raise AdapterException(f"Blockchain type '{chain_type}' is not supported")
        
        # 如果已有实例且不需要重新配置，则返回缓存的实例
        if chain_type in self.adapters and config is None:
            logger.debug(f"Returning cached adapter for {chain_type}")
            return self.adapters[chain_type]
        
        # 创建新的适配器实例
        adapter_class = self.adapter_classes[chain_type]
        adapter = adapter_class(config or {})
        
        # 缓存实例
        self.adapters[chain_type] = adapter
        logger.info(f"Created new adapter for {chain_type}")
        
        return adapter
    
    def create_adapter(self, chain_type: str, config: Dict[str, Any] = None) -> BaseBlockchainAdapter:
        """创建指定类型的区块链适配器实例
        
        Args:
            chain_type: 区块链类型
            config: 适配器配置参数
            
        Returns:
            区块链适配器实例
            
        Raises:
            ChainNotSupportedException: 如果指定的区块链类型不受支持
        """
        return self.get_adapter(chain_type, config)
    
    def get_supported_chains(self) -> list:
        """获取支持的区块链类型列表
        
        Returns:
            支持的区块链类型列表
        """
        return list(self.adapter_classes.keys())
    
    async def close_all(self) -> None:
        """关闭所有适配器连接"""
        for chain_type, adapter in self.adapters.items():
            try:
                await adapter.close_connection()
                logger.info(f"Closed connection for {chain_type} adapter")
            except Exception as e:
                logger.error(f"Error closing {chain_type} adapter: {str(e)}")
        
        self.adapters = {}
    
    async def close_adapter(self, chain_type: str) -> None:
        """关闭指定适配器连接
        
        Args:
            chain_type: 区块链类型
        """
        if chain_type in self.adapters:
            try:
                await self.adapters[chain_type].close_connection()
                del self.adapters[chain_type]
                logger.info(f"Closed connection for {chain_type} adapter")
            except Exception as e:
                logger.error(f"Error closing {chain_type} adapter: {str(e)}")
    
    def register_adapter_class(self, chain_type: str, adapter_class: type) -> None:
        """注册新的适配器类
        
        Args:
            chain_type: 区块链类型
            adapter_class: 适配器类
        """
        self.adapter_classes[chain_type] = adapter_class
        logger.info(f"Registered new adapter class for {chain_type}")
    
    def get_adapter_status(self, chain_type: str) -> Optional[Dict[str, Any]]:
        """获取适配器状态
        
        Args:
            chain_type: 区块链类型
            
        Returns:
            适配器状态信息，如果适配器不存在则返回None
        """
        if chain_type not in self.adapters:
            return None
        
        adapter = self.adapters[chain_type]
        return {
            'chain_type': chain_type,
            'connected': adapter.is_connected(),
            'config': adapter.get_config_summary(),
            'last_activity': adapter.last_activity_time
        }